/**
 * 性能监控工具
 */

import { logger } from '../../utils/logger';

export interface PerformanceMetrics {
  name: string;
  duration: number;
  startTime: number;
  endTime: number;
  memoryUsage?: number;
  metadata?: Record<string, unknown>;
}

export interface PerformanceReport {
  totalMetrics: number;
  averageDuration: number;
  slowestOperation: PerformanceMetrics | null;
  fastestOperation: PerformanceMetrics | null;
  memoryPeak: number;
  timeRange: {
    start: number;
    end: number;
  };
}

class PerformanceMonitor {
  private metrics: PerformanceMetrics[] = [];
  private activeTimers: Map<string, number> = new Map();
  private maxMetrics = 1000; // 最大保存的指标数量

  /**
   * 开始性能计时
   */
  start(name: string, metadata?: Record<string, unknown>): void {
    const startTime = performance.now();
    this.activeTimers.set(name, startTime);
    
    logger.debug(`Performance timer started: ${name}`, metadata);
  }

  /**
   * 结束性能计时
   */
  end(name: string, metadata?: Record<string, unknown>): PerformanceMetrics | null {
    const endTime = performance.now();
    const startTime = this.activeTimers.get(name);

    if (!startTime) {
      logger.warn(`Performance timer not found: ${name}`);
      return null;
    }

    this.activeTimers.delete(name);

    const metric: PerformanceMetrics = {
      name,
      duration: endTime - startTime,
      startTime,
      endTime,
      memoryUsage: this.getMemoryUsage(),
      metadata,
    };

    this.addMetric(metric);
    
    logger.debug(`Performance timer ended: ${name} (${metric.duration.toFixed(2)}ms)`);
    
    return metric;
  }

  /**
   * 测量函数执行时间
   */
  async measure<T>(
    name: string,
    fn: () => Promise<T> | T,
    metadata?: Record<string, unknown>,
  ): Promise<T> {
    this.start(name, metadata);
    
    try {
      const result = await fn();
      this.end(name, metadata);
      return result;
    } catch (error) {
      this.end(name, { ...metadata, error: (error as Error).message });
      throw error;
    }
  }

  /**
   * 添加性能指标
   */
  private addMetric(metric: PerformanceMetrics): void {
    this.metrics.push(metric);

    // 保持指标数量在限制内
    if (this.metrics.length > this.maxMetrics) {
      this.metrics.shift();
    }
  }

  /**
   * 获取内存使用情况
   */
  private getMemoryUsage(): number {
    if (typeof performance !== 'undefined' && (performance as any).memory) {
      return (performance as any).memory.usedJSHeapSize;
    }
    return 0;
  }

  /**
   * 获取性能报告
   */
  getReport(timeRange?: { start: number; end: number }): PerformanceReport {
    let filteredMetrics = this.metrics;

    if (timeRange) {
      filteredMetrics = this.metrics.filter(
        metric => metric.startTime >= timeRange.start && metric.endTime <= timeRange.end,
      );
    }

    if (filteredMetrics.length === 0) {
      return {
        totalMetrics: 0,
        averageDuration: 0,
        slowestOperation: null,
        fastestOperation: null,
        memoryPeak: 0,
        timeRange: timeRange || { start: 0, end: 0 },
      };
    }

    const durations = filteredMetrics.map(m => m.duration);
    const memoryUsages = filteredMetrics
      .map(m => m.memoryUsage || 0)
      .filter(usage => usage > 0);

    const slowestOperation = filteredMetrics.reduce((prev, current) =>
      prev.duration > current.duration ? prev : current,
    );

    const fastestOperation = filteredMetrics.reduce((prev, current) =>
      prev.duration < current.duration ? prev : current,
    );

    return {
      totalMetrics: filteredMetrics.length,
      averageDuration: durations.reduce((sum, duration) => sum + duration, 0) / durations.length,
      slowestOperation,
      fastestOperation,
      memoryPeak: memoryUsages.length > 0 ? Math.max(...memoryUsages) : 0,
      timeRange: timeRange || {
        start: Math.min(...filteredMetrics.map(m => m.startTime)),
        end: Math.max(...filteredMetrics.map(m => m.endTime)),
      },
    };
  }

  /**
   * 获取指定名称的指标
   */
  getMetricsByName(name: string): PerformanceMetrics[] {
    return this.metrics.filter(metric => metric.name === name);
  }

  /**
   * 清除所有指标
   */
  clear(): void {
    this.metrics = [];
    this.activeTimers.clear();
  }

  /**
   * 设置最大指标数量
   */
  setMaxMetrics(max: number): void {
    this.maxMetrics = max;
    
    if (this.metrics.length > max) {
      this.metrics = this.metrics.slice(-max);
    }
  }

  /**
   * 导出指标数据
   */
  exportMetrics(): PerformanceMetrics[] {
    return [...this.metrics];
  }

  /**
   * 获取慢查询（超过阈值的操作）
   */
  getSlowOperations(threshold: number = 1000): PerformanceMetrics[] {
    return this.metrics.filter(metric => metric.duration > threshold);
  }
}

// 创建全局性能监控实例
export const performanceMonitor = new PerformanceMonitor();

/**
 * 性能监控装饰器
 */
export function Monitor(name?: string) {
  return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value;
    const monitorName = name || `${target.constructor.name}.${propertyName}`;

    descriptor.value = async function (...args: any[]) {
      return performanceMonitor.measure(
        monitorName,
        () => method.apply(this, args),
        { className: target.constructor.name, methodName: propertyName },
      );
    };

    return descriptor;
  };
}